#include "bsp_at24cxx.h"
#include "bsp_system_clock.h"

/*******************************************************************************
* 函数功能 : 延时函数
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_delay(void){
	delay_us(2);
}
/*******************************************************************************
* 函数功能 : 延时函数
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_delay_ms(void){
	delay_ms(5);
}
/*******************************************************************************
* 函数功能 : 拉低sck时钟线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_sck_l(void){
	gpio_bit_reset(GPIOB,GPIO_PIN_6);
}
/*******************************************************************************
* 函数功能 : 拉高sck时钟线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_sck_h(void){
	gpio_bit_set(GPIOB,GPIO_PIN_6);
}
/*******************************************************************************
* 函数功能 : 拉低sda数据线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_sda_l(void){
	gpio_bit_reset(GPIOB,GPIO_PIN_7);
}
/*******************************************************************************
* 函数功能 : 拉高sda数据线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_sda_h(void){
	gpio_bit_set(GPIOB,GPIO_PIN_7);
}
/*******************************************************************************
* 函数功能 : 设置sda为输出
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_sda_out(void){
//	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_7);
//	gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
}
/*******************************************************************************
* 函数功能 : 设置sda为输入
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void at24c02_sda_in(void){
//	gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_7);
}
/*******************************************************************************
* 函数功能 : 读取sda数据
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static uint8_t at24c02_sda_read(void){
	return gpio_input_bit_get(GPIOB,GPIO_PIN_7);
}
/*******************************************************************************
* 函数功能 : 读取一个字节数据
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
uint8_t at24c02_read_byte(soft_iic_dev_t *dev, uint8_t readAddr){
	uint8_t ch = 0;
	soft_iic_start(dev);
	soft_iic_send_byte(dev,dev->slave_addr);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,readAddr);
	soft_iic_wait_ack(dev);
	
	soft_iic_start(dev);
	soft_iic_send_byte(dev,dev->slave_addr+1);
	soft_iic_wait_ack(dev);
	ch = soft_iic_read_byte(dev, 0);
	soft_iic_stop(dev);
	return ch;
}
/*******************************************************************************
* 函数功能 : 读取多个字节数据
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void at24c02_read_buf(soft_iic_dev_t *dev, uint16_t readAddr, uint8_t *buf, uint16_t len){
	for(int i=0;i<len;i++){
		buf[i] = at24c02_read_byte(dev,readAddr++);
	}
}
/*******************************************************************************
* 函数功能 : 写入单个字节
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void at24c02_write_byte(soft_iic_dev_t *dev, uint8_t writeAddr, uint8_t ch){
	soft_iic_start(dev);
	soft_iic_send_byte(dev,dev->slave_addr);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,writeAddr);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,ch);
	soft_iic_wait_ack(dev);
	soft_iic_stop(dev);
	dev->delay_ms();
}
/*******************************************************************************
* 函数功能 : 写入多个字节
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void at24c02_write_buf(soft_iic_dev_t *dev, uint8_t writeAddr, uint8_t *buf, uint16_t len){
	for(int i=0;i<len;i++){
		at24c02_write_byte(dev,writeAddr++,buf[i]);
	}
}
/***************************************************************************************************************************/

soft_iic_dev_t at24c02_dev = {
	.delay = at24c02_delay,
	.name = "AT24C02_EEPROM",
	.reg_addr = 0x00,
	.SCK_L = at24c02_sck_l,
	.SCK_H = at24c02_sck_h,
	.SDA_L = at24c02_sda_l,
	.SDA_H = at24c02_sda_h,
	.SDA_IN = at24c02_sda_in,
	.SDA_OUT = at24c02_sda_out,
	.SDA_READ = at24c02_sda_read,
	.delay_ms = at24c02_delay_ms,
	.slave_addr = 0xA0,
};

/*******************************************************************************
* 函数功能 : 初始化AT24C02的引脚
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void bsp_at24c02_gpio_init(void){
	rcu_periph_clock_enable(RCU_GPIOB);
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_6);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
	
	//配置成开漏输出，上拉模式，可以不用修改SDA的输入输出方式
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_7);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
}

uint8_t rxbuf[8] = {0};
uint8_t txbuf[8] = "92389789";
void bsp_at24c02_init(void){
	bsp_at24c02_gpio_init();
	at24c02_write_buf(&at24c02_dev, at24c02_dev.reg_addr, txbuf, sizeof(txbuf));
	at24c02_read_buf(&at24c02_dev, at24c02_dev.reg_addr, rxbuf, sizeof(rxbuf));
}

